/* 
 * 
 * Copyright (c) 2007 John Wells
 * Copyright (c) 2010 Photonic Games

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

using System;
using System.IO;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Graphics;

namespace GameLevel.ContentPipeline.Leadwerks14
{
    [ContentImporter(".3DW", DisplayName = "Level (.3dw) - John Wells", DefaultProcessor = "Leadwerks14LevelProcessor")]
    internal class Leadwerks14Importer : ContentImporter<Leadwerks14Content>
    {
        #region Methods
        /// <summary>This method is required for participation in the XNA Content Pipeline as a Content Importer</summary>
        public override Leadwerks14Content Import(string filename, ContentImporterContext context)
        {
            // Uncomment the next line to debug the import process
            //System.Diagnostics.Debugger.Launch();

            // Open the file into a BinaryReader object so we can parse it
            using (Stream stream = File.OpenRead(filename))
            using (BinaryReader reader = new BinaryReader(stream))
            {
                // Read the content
                Leadwerks14Content content = Leadwerks14Content.Read(reader, context);

                // Retain the content filename for later
                content.Identity = new ContentIdentity(filename);

                // Update the objects that are waiting on real objects (they currently just have
                // indexes and such, but we'd rather expose real values, not indexes to them...)
                
                // Material for brush faces
                foreach (Brush brush in content.Brushes)
                    foreach (BrushFace face in brush.VisibleFaces)
                    {
                        // This is the .3dw material that represent basically just the texture name
                        face.Material = content.Materials[face.MaterialIndex];
                    }

                // Material for terrains
                foreach (Terrain terrain in content.Terrains)
                    foreach (Terrain.Layer layer in terrain.layers)
                    {
                        // This is the .3dw material that represent basically just the texture name
                        layer.material = content.Materials[layer.materialIndex];
                    }
                return content;
            }
        }

        /// <summary>Helper method to get a null terminated ASCII encoded string from an
        /// opened binary reader object</summary>
        public static string ReadString(BinaryReader reader)
        {
            // Use a string builder to build up this string
            StringBuilder sb = new StringBuilder();
            Encoding encoding = new ASCIIEncoding();

            // Read the first byte
            byte value = reader.ReadByte();

            // Loop so long as the value isn't null/0
            while (value != 0x00)
            {
                // Add the ASCII representation of this character to the string builder
                sb.Append(encoding.GetString(new byte[] { value }));

                // Read the next byte
                value = reader.ReadByte();
            }

            // The string builder now includes all characters up to and not including
            // the null terminator for this string
            return sb.ToString();
        }

        /// <summary>Helper method to get a Vector2 from an opened binary reader object</summary>
        public static Vector2 ReadVector2(BinaryReader reader)
        {
            // Packed as x, then y
            float x = reader.ReadSingle();
            float y = reader.ReadSingle();

            return new Vector2(x, y);
        }

        /// <summary>Helper method to get a Vector3 from an opened binary reader object</summary>
        public static Vector3 ReadVector3(BinaryReader reader)
        {
            // Packed as x, y, then z
            float x = reader.ReadSingle();
            float y = reader.ReadSingle();
            float z = reader.ReadSingle();

            return new Vector3(x, y, -z);
        }

        /// <summary>Helper method to get a Plane from an opened binary reader object</summary>
        public static Plane ReadPlane(BinaryReader reader)
        {
            // Packed as a, b, c, then d
            float a = reader.ReadSingle();
            float b = reader.ReadSingle();
            float c = reader.ReadSingle();
            float d = reader.ReadSingle();

            return new Plane(a, b, c, d);
        }

        /// <summary>Helper method to get a Color from an opened binary reader object</summary>
        public static Color ReadColor(BinaryReader reader)
        {
            // Packed as r, g, then b
            return new Color(reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
        }
        #endregion
    }
}
